package com.rengwuxian.coursecoroutines._3_scope_context

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.job
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlin.coroutines.ContinuationInterceptor
import kotlin.coroutines.CoroutineContext

/**
 * CoroutineScope 和 CoroutineContext 的定位
 * CoroutineScope、CoroutineContext、Job、launch()/async()
 *
 * + 号，可以合并两个CoroutineContext
 *
 * CoroutineContext：协程上下文，哪些东西是上下文呢？全部都是，比如：Job和ContinuationInterceptor
 *                   根据功能不同，化成了不同的分类，比如管理流程用的是Job，管理线程的是ContinuationInterceptor，以及其他的
 *
 * CoroutineScope 是CoroutineContext的容器，是每个协程的coroutineContext的容器。每个协程的大括号，都有一个CoroutineScope这样一个容器。
 *                作用之一：用这个CoroutineScope中的coroutineContext这个属性来保留大括号中协程代码块的上下文信息。
 *                作用之二：启动子协程（除了runBlocking之外）
 * 所以创建协程就自带了上下文信息，直接拿它的coroutineContext属性来用。
 *
 * val scope = CoroutineScope(Dispatchers.IO)
 * 手动创建的CoroutineScope是没有任何上下文信息，也不需要的，因为外部没有对应的协程。但会有自己的Job，但是没有自己的协程。（从代码块的角度）
 * 拥有了上下文信息，也就方便启动子协程了，呼应了上面。
 */
fun main() = runBlocking<Unit> {
  val context = Dispatchers.IO + Job() + Job()
  val scope = CoroutineScope(Dispatchers.IO)
  val job = scope.launch {
    this.coroutineContext[Job]
    coroutineContext.job
    coroutineContext[ContinuationInterceptor]
  }
  delay(10000)
}